package com.gopay.controller;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.gopay.common.Result;
import com.gopay.common.constants.bank.BankConstants;
import com.gopay.common.constants.bank.KhPayConstants;
import com.gopay.common.domain.bank.khpay.ebank.KhPayMessage;
import com.gopay.common.exception.GopayException;
import com.gopay.common.util.SendMail;
import com.gopay.remote.bank.BankInteractRemoteService;

/**
 * 平安跨行支付手动发起下载对账文件
 * 
 * @KhPayDownloadOrderController.java
 * @author zhengxue
 * @2017-11-29 上午10:02:01 www.gopay.com.cn Inc.All rights reserved.
 */
@Controller
@Scope("prototype")
public class KhPayDownloadOrderController {

    private static Logger logger = LoggerFactory.getLogger(KhPayDownloadOrderController.class);

    @Resource(name = "khPayDayEndConfig")
    private Map<String, String> khPayDayEndConfig;

    @Resource(name = "bankClient")
    private BankInteractRemoteService bankClient;

    /**
     * 
     * @param HttpServletRequest
     * @param HttpServletResponse
     * @return ModelAndView
     */
    @RequestMapping(value = "/kHPayDownloadOrder", method = { RequestMethod.GET })
    protected void execute(HttpServletRequest request, HttpServletResponse response) {
        logger.error("KhPayDownloadOrderController: start ");
        try {
            // 生成对账单文件所需参数
            String locpath = khPayDayEndConfig.get("locpath");
            // String fTime = DateUtils.getYesterday();
            String fTime = request.getParameter("data");

            String fName = "khPayBill-" + fTime + ".txt";
            List sendFile = new ArrayList();
            List names = new ArrayList();
            String messageText = "";

            File file = new File(locpath + fName);
            // 判断本地服务器是否存在代扣对账文件
            if (!file.exists()) {
                // 如果不存在对账文件，查对账单并生成文件
                boolean flag = getKhPayadjust(fTime);
                if (flag) {
                    logger.error("KhPayDownloadOrderController " + fName + " 对账文件请求成功!");
                } else {
                    logger.error("KhPayDownloadOrderController " + fName + " 对账文件请求失败!");
                }
                return;
            } else {
                logger.error("KhPayDownloadOrderController " + fName + " 对账文件已存在!");
                String lastLine = readLastLine(file, "UTF-8");
                if (lastLine.trim().equals("########")) {
                    names.add(fName);
                } else {
                    if (lastLine.trim().equals("end")) {
                        // 对账文件已发送邮件
                        logger.error("KhPayDownloadOrderController " + fName + " 对账文件已发送邮件!");
                        return;
                    }
                }
            }

            // 若对账文件全部为空，则邮件内容标明
            if (names.size() < 1) {
                logger.error("KhPayDownloadOrderController: 平安跨行支付对账文件为null或本地已成功下载!");
                return;
            } else {
                messageText = fTime + ": 平安跨行支付对账文件见附件!" + fName;
                for (int i = 0; i < names.size(); i++) {
                    sendFile.add(locpath + (String) names.get(i));
                }
            }
            String subject = "平安跨行支付对账文件";
            String[] cc = khPayDayEndConfig.get("sendmail.cc").split(","); // 获取多个抄送人
            List ccList = Arrays.asList(cc);
            // 发送邮件
            SendMail.sendMessage(khPayDayEndConfig.get("sendmail.host"), khPayDayEndConfig.get("sendmail.sender"),
                    khPayDayEndConfig.get("sendmail.username"), khPayDayEndConfig.get("sendmail.password"),
                    khPayDayEndConfig.get("sendmail.receiver"), subject, messageText, "text/html;charset=gb2312",
                    ccList, sendFile, names);
            logger.error("------平安跨行支付发送邮件成功--------");
            // 写入对账文件已发送邮件标识
            writeFiles(locpath + fName);
        } catch (Exception e) {
            logger.error("KhPayDownloadOrderController error: ", e);
        }
    }

    /**
     * 接口查对账单
     * 
     * @return
     */
    private boolean getKhPayadjust(String fTime) {
        boolean flag = false;
        KhPayMessage message = new KhPayMessage();
        message.setBank(BankConstants.BANK_LOGO_KHPAY);
        message.setTradeType(2);
        message.setOrderDate(fTime);
        Result result = bankClient.dayend(message);
        KhPayMessage resMsg = (KhPayMessage) result.getDefaultModel();
        if (KhPayConstants.RES_CODE_SUCCESS.equals(resMsg.getRetCode())) {
            logger.error("KhPayDownloadOrderController dayend query success");
            flag = true;
        }
        return flag;
    }

    /**
     * 获取对账文件最后一行数据
     * 
     * @param file
     * @param charset
     * @return
     * @throws IOException
     */
    public static String readLastLine(File file, String charset) throws IOException {
        if (!file.exists() || file.isDirectory() || !file.canRead()) {
            return null;
        }
        RandomAccessFile raf = null;
        try {
            raf = new RandomAccessFile(file, "r");
            long len = raf.length();
            if (len == 0L) {
                return "";
            } else {
                long pos = len - 1;
                while (pos > 0) {
                    pos--;
                    raf.seek(pos);
                    if (raf.readByte() == '\n') {
                        break;
                    }
                }
                if (pos == 0) {
                    raf.seek(0);
                }
                byte[] bytes = new byte[(int) (len - pos)];
                raf.read(bytes);
                if (charset == null) {
                    return new String(bytes);
                } else {
                    return new String(bytes, charset);
                }
            }
        } catch (FileNotFoundException e) {
        } finally {
            if (raf != null) {
                try {
                    raf.close();
                } catch (Exception e2) {
                }
            }
        }
        return null;
    }

    public void writeFiles(String filePath) throws GopayException {
        FileWriter fw = null;
        try {
            File file = new File(filePath);
            fw = new FileWriter(file, true);
            fw.write("end");
            fw.flush();
            fw.close();
        } catch (IOException e) {
            logger.error("KhPayDownloadOrderController write end error: ", e);
        } finally {
            if (fw != null) {
                try {
                    fw.close();
                } catch (IOException e) {
                    logger.error("KhPayDownloadOrderController close error: ", e);
                }
            }
        }
    }
}
